using System;
using System.Collections.Generic;
using System.ComponentModel;
using Microsoft.Ccr.Core;
using Microsoft.Dss.Core.Attributes;
using Microsoft.Dss.ServiceModel.Dssp;
using Microsoft.Dss.ServiceModel.DsspServiceBase;
using dssp = Microsoft.Dss.ServiceModel.Dssp;
using submgr = Microsoft.Dss.Services.SubscriptionManager;
using drive = Microsoft.Robotics.Services.Drive.Proxy;
using blob = Microsoft.Robotics.Services.Sample.BlobTracker.Proxy;
using W3C.Soap;
using System.Drawing;
using AForge.Robotics.Surveyor;
using System.IO;
using System.Drawing.Imaging;

namespace ExampleSRV1App
{
	[Contract(Contract.Identifier)]
	[DisplayName("ExampleSRV1App")]
	[Description("Provides acces to the Surveyor SRV-1 controller service")]
	class AForgeNetService : DsspServiceBase
	{
		[ServiceState]
		AForgeNetState _state = new AForgeNetState();
		
		[ServicePort("/ExampleSRV1App", AllowMultipleInstances = true)]
		AForgeNetOperations _mainPort = new AForgeNetOperations();

        [Partner(dssp.Partners.SubscriptionManagerString, Contract = submgr.Contract.Identifier, CreationPolicy = PartnerCreationPolicy.CreateAlways)]
        submgr.SubscriptionManagerPort _subMgrPort = new submgr.SubscriptionManagerPort();

        [Partner("Drive", Contract = drive.Contract.Identifier, CreationPolicy = PartnerCreationPolicy.UseExistingOrCreate)]
        drive.DriveOperations _srv1DrivePort = new drive.DriveOperations();

        [Partner("BlobTracker", Contract = blob.Contract.Identifier, CreationPolicy = PartnerCreationPolicy.UseExistingOrCreate)]
        blob.BlobTrackerOperations _blobPort = new blob.BlobTrackerOperations();
        blob.BlobTrackerOperations _blobNotify = new blob.BlobTrackerOperations();
		
        // SRV-1
        static internal AForgeNetController.AForgeNetController Srv1Controller = null;

		public AForgeNetService(DsspServiceCreationPort creationPort)
			: base(creationPort)
		{
		}
		
		protected override void Start()
		{
            base.Start();

            _blobPort.Subscribe(_blobNotify);
            Activate<ITask>(Arbiter.Receive<blob.ImageProcessed>(true, _blobNotify, OnImageProcessed));
		}

        /// <summary>
        /// Get Handler returns Srv1Service State.
        /// </summary>
        /// <param name="get"></param>
        [ServiceHandler(ServiceHandlerBehavior.Concurrent)]
        public IEnumerator<ITask> GetHandler(Get get)
        {
            get.ResponsePort.Post(_state);
            yield break;
        }

        /// <summary>
        /// Drop Handler shuts down Srv1Service
        /// </summary>
        /// <param name="drop"></param>
        [ServiceHandler(ServiceHandlerBehavior.Teardown)]
        public IEnumerator<ITask> DropHandler(DsspDefaultDrop drop)
        {
            base.DefaultDropHandler(drop);
            yield break;
        }

        /// <summary>
        /// Handles Subscribe messages
        /// </summary>
        /// <param name="subscribe">the subscribe request</param>
        [ServiceHandler]
        public void SubscribeHandler(Subscribe subscribe)
        {
            SubscribeHelper(_subMgrPort, subscribe.Body, subscribe.ResponsePort);
        }

        // Imaged Processed Handler
        void OnImageProcessed(blob.ImageProcessed imageProcessed)
        {
            drive.RotateDegreesRequest driveRequestDegrees = new Microsoft.Robotics.Services.Drive.Proxy.RotateDegreesRequest();
            drive.DriveDistanceRequest driveDistanceRequest = new Microsoft.Robotics.Services.Drive.Proxy.DriveDistanceRequest();
            driveRequestDegrees.Degrees = 30;
            driveDistanceRequest.Distance = .3;

            if (imageProcessed.Body.Results.Count == 1)
            {
                if (imageProcessed.Body.Results[0].Area > 100)
                {
                    _srv1DrivePort.DriveDistance(driveDistanceRequest);
                }
                else
                {
                    _srv1DrivePort.RotateDegrees(driveRequestDegrees);
                }
            }

        }
	}
}


